package com.kye.express.business.personal_setting;

import android.support.annotation.NonNull;

import com.kye.express.contract.base.BasePresenter;
import com.kye.express.contract.base.view.ErrorView;
import com.kye.express.contract.base.view.IView;
import com.kye.express.contract.base.view.LoadingView;
import com.kye.model.OpenApiResultObserver;
import com.kye.model.SharedPreferencesManager;
import com.kye.model.UserSession;
import com.kye.model.base.RetrofitManager;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.user.User;
import com.kye.model.bean.user.request.RequestEditPersonalSetting;
import com.kye.model.bean.user.request.RequestGetUser;
import com.kye.model.service.UserService;

import java.util.Date;

import io.reactivex.Single;
import io.reactivex.SingleSource;
import io.reactivex.SingleTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.BiConsumer;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;

public interface PersonalSettingContract {

    interface PersonalSettingView extends IView, LoadingView, ErrorView {

        void onUser(User user);

        void onIsPush(Boolean isPush);

        void onLogout();
    }

    class PersonalSettingPresenter extends BasePresenter<PersonalSettingView> {
        @Override
        public void bind(PersonalSettingView view) {
            super.bind(view);

            UserSession.getInstance()
                    .getUserForRx()
                    .compose(getView().<User>bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<User>() {
                        @Override
                        public void accept(User user) throws Exception {
                            getView().onUser(user);
                        }
                    });
        }

        public void logout() {
            RetrofitManager.getInstance().createOpenApiService(UserService.class).logout()
                    .onErrorReturn(new Function<Throwable, OpenApiResult<Object>>() {
                        @Override
                        public OpenApiResult<Object> apply(Throwable throwable) throws Exception {
                            OpenApiResult<Object> openApiResult = new OpenApiResult<>();
                            openApiResult.setSuccess(true);
                            return openApiResult;
                        }
                    })
                    .doOnEvent(new BiConsumer<OpenApiResult<Object>, Throwable>() {
                        @Override
                        public void accept(OpenApiResult<Object> objectOpenApiResult, Throwable throwable) throws Exception {
                            UserSession.getInstance().setUser(null);

                            SharedPreferencesManager.clear();
                        }
                    })
                    .compose(getView().<OpenApiResult<Object>>bindToLifecycleDestroy())
                    .compose(getLoading())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<Object>() {
                        @Override
                        public void onOtherError(Throwable e) {
                            getView().onError();
                        }

                        @Override
                        public void onLoading(Disposable d) {
//                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<Object> result, Object o) {
                            getView().onLogout();
                        }

                        @Override
                        public void onApiError(OpenApiResult<Object> result, int code, String msg) {
                            getView().onError(msg);
                        }

                        @Override
                        public void onLoaded() {
//                            getView().onLoaded();
                        }
                    });
        }

        @NonNull
        public SingleTransformer<OpenApiResult<Object>, OpenApiResult<Object>> getLoading() {
            return new SingleTransformer<OpenApiResult<Object>, OpenApiResult<Object>>() {
                @Override
                public SingleSource<OpenApiResult<Object>> apply(Single<OpenApiResult<Object>> upstream) {
                    return upstream.doOnSubscribe(new Consumer<Disposable>() {
                        @Override
                        public void accept(Disposable disposable) throws Exception {
                            getView().onLoading();
                        }
                    })
                            .doFinally(new Action() {
                                @Override
                                public void run() throws Exception {
                                    getView().onLoaded();
                                }
                            });
                }
            };
        }

        public void editPersonalSetting(User user, String gender) {
            editPersonalSetting(user, null, gender, null, null);
        }

        public void editPersonalSetting(User user, Date birthday) {
            editPersonalSetting(user, null, null, null, birthday);
        }

        public void editPersonalSetting(final User user, String name, String gender, String company, Date birthday) {
            RetrofitManager.getInstance()
                    .createOpenApiService(UserService.class)
                    .editPersonalSetting(new RequestEditPersonalSetting(user.getPhone(), name, gender, company, birthday))
                    .flatMap(new Function<OpenApiResult<Object>, SingleSource<OpenApiResult<User>>>() {
                        @Override
                        public SingleSource<OpenApiResult<User>> apply(OpenApiResult<Object> objectOpenApiResult) throws Exception {
                            return RetrofitManager.getInstance()
                                    .createOpenApiService(UserService.class)
                                    .getUser(new RequestGetUser(user.getPhone()));
                        }
                    })
                    .doOnSuccess(new Consumer<OpenApiResult<User>>() {
                        @Override
                        public void accept(OpenApiResult<User> userOpenApiResult) throws Exception {
                            User newUser = userOpenApiResult.getData();
                            if (newUser == null) return;
                            newUser.setToken(user.getToken());
                            newUser.setRefreshToken(user.getRefreshToken());

                            UserSession.getInstance().setUser(newUser);
                        }
                    })
                    .compose(getView().<OpenApiResult<User>>bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<User>() {
                        @Override
                        public void onOtherError(Throwable e) {
                            getView().onError();
                        }

                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<User> result, User user) {
                        }

                        @Override
                        public void onApiError(OpenApiResult<User> result, int code, String msg) {
                            getView().onError(msg);
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }
    }
}
